package com.njtech.pet.service.impl;

import com.njtech.pet.constant.Constant;
import com.njtech.pet.dao.*;
import com.njtech.pet.entity.SingleRecord;
import com.njtech.pet.service.StatisticService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;

/**
 * Author:cw
 * Date:2020-04-13 22:14
 * Description:StatisticService中方法的实现
 */
@Service
@Transactional(propagation = Propagation.REQUIRED,rollbackFor = Exception.class)
public class StatisticServiceImpl implements StatisticService{

    @Autowired
    @Resource(name = "staticDao")
    private StaticDao staticDao;


    /**
     * 根据用户等级显示总用户人数
     * @param ifMember ifMember == false时返回注册成为用户的总人数，ifMember == true时返回注册成为会员的人数
     * @return 人数
     */
    @Override
    public Integer showTotalUserNum(Boolean ifMember) {
        if(ifMember == false) {
            Integer userNum = staticDao.getUserNumInDays(null, false, Constant.User.STATE_VALID.getValue());
            Integer memberNum = staticDao.getUserNumInDays(null, true, Constant.User.STATE_VALID.getValue());
            return (userNum + memberNum);
        }
        else {
            Integer memberNum = staticDao.getUserNumInDays(null, true, Constant.User.STATE_VALID.getValue());
            System.out.println(memberNum);
            return memberNum;
        }
    }


    /**
     * 根据商品类别显示总商品数
     * @param type 商品类别：优惠卷，各种类别的保险
     * @return 返回数目
     */
    @Override
    public Integer showTotalItemNum(String type) {
        Integer iNum = staticDao.getItemNumInDaysByTypeAndStateAndSubject(null, type, Constant.Item.STATE_VALID.getValue(), null);
        Integer mNum = staticDao.getItemNumInDaysByTypeAndStateAndSubject(null, type, Constant.Item.STATE_PERMANENT.getValue(), null);
        return (iNum + mNum);
    }

    /**
     * 根据订单状态显示该状态的订单数
     * @param state 订单状态：订单已支付，订单已取消
     * @return 返回数目
     */
    @Override
    public Integer showTotalBillNum(String state) {
        return staticDao.getBillNumInDaysByTypeAndState(null,null,state);
    }


    /**
     * 显示当月(当日往前28天)内活跃的用户,会员人数，把月份分成4个星期，返回这4个星期内分别增长的值
     * @param ifMember ifMember == false时返回注册成为用户的总人数，ifMember == true时返回注册成为会员的人数
     * @return 返回list数组(0对应28天内离当前最近的一周，依次4代表28天离当前最远的一周)
     */
    @Override
    public List<Integer> showActiveUserOrMemberNumInWeek(Boolean ifMember) {
        if(!ifMember) {
            List<Integer> list = new ArrayList<>();
            Integer num, temporaryNum = 0;
            for(int i = 0;i < 4;i++)
            {
                num = staticDao.getActiveUserNumInDays((i+1)*7, false) - temporaryNum;
                temporaryNum += num;
                list.add(i,num);
            }
            return list;
        }
        else {
            List<Integer> list = new ArrayList<>();
            Integer num, temporaryNum = 0;
            for(int i = 0;i < 4;i++)
            {
                num = staticDao.getActiveUserNumInDays((i+1)*7, true) - temporaryNum;
                temporaryNum += num;
                list.add(i,num);
            }
            return list;
        }
    }

    /**
     * 显示当月新增的商品，把月份分成4个星期，返回这4个星期内分别增长的值
     * @param type 商品类型
     * @param state 商品状态
     * @param subject 险别
     * @return 返回list数组(0对应28天内离当前最近的一周，依次4代表28天离当前最远的一周)
     */
    @Override
    public List<Integer> showItemNumInWeek(String type, String state, String subject) {
        List<Integer> list = new ArrayList<>();
        Integer num, temporaryNum = 0;
        for(int i = 0;i < 4;i++)
        {
            //减去上几周的人数
            num = staticDao.getItemNumInDaysByTypeAndStateAndSubject((i+1)*7, type, state, subject) - temporaryNum;
            temporaryNum += num;
            list.add(i,num);
        }
        return list;
    }

    /**
     * 显示当月新增的订单，把月份分成4个星期，返回这4个星期内分别增长的值
     * @param type 订单类别
     * @param state 订单状态
     * @return 返回list数组(0对应28天内离当前最近的一周，依次4代表28天离当前最远的一周)
     */
    @Override
    public List<Integer> showBillNumInWeek(String type, String state) {
        List<Integer> list = new ArrayList<>();
        Integer num, temporaryNum = 0;
        for(int i = 0;i < 4;i++)
        {
            //减去上几周的人数
            num = staticDao.getBillNumInDaysByTypeAndState((i+1)*7, type, state) - temporaryNum;
            temporaryNum += num;
            list.add(i,num);
        }
        return list;
    }

    /**
     * 显示count月(如12个月)对应类别状态的订单数目
     * @param count 月份
     * @param type 订单类别
     * @param state 订单状态
     * @return 格式为：{name='yyyy-MM', value='*'}的List
     */
    @Override
    public List<SingleRecord> showBillNumByMonth(Integer count, String type, String state) {
        return staticDao.getBillCountInDate(count, type, state, "%Y-%m");
    }

    /**
     * 显示count月(如12个月)对应类别状态的新增商品数目
     * @param count 月份
     * @param type 商品类别
     * @param state 商品状态
     * @param subject 险别
     * @return 格式为：{name='yyyy-MM', value='*'}的List
     */
    @Override
    public List<SingleRecord> showItemNumByMonth(Integer count, String type, String state, String subject) {
        return staticDao.getItemCountInDate(count, type, state, "%Y-%m", subject);
    }

    /**
     * 显示过去count年/月/天/周前开始到现在 类型为action，状态为state的数目
     * @param count 月份
     * @param action 行为
     * @param state 状态
     * @return
     */
    @Override
    public List<SingleRecord> showActionNumByMonth(Integer count, String action, String state) {
        return staticDao.getActionCountInDate(count, "%Y-%m", action, state);
    }
}
